* A more accurate check cannot be done with a single comparison.
*/
if ( (act->pin & 0x80808080U) != 0 )
- PIN_FAIL(unlock_out, ENOSPC, "Risk of counter overflow %08x\n", act->pin);
+ PIN_FAIL(unlock_out, ENOSPC,
+ "Risk of counter overflow %08x\n", act->pin);
frame = act->frame;
if ( dev_hst_ro_flags & GNTMAP_device_map )
act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
GNTPIN_devr_inc : GNTPIN_devw_inc;
+
if ( dev_hst_ro_flags & GNTMAP_host_map )
act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
GNTPIN_hstr_inc : GNTPIN_hstw_inc;
}
- /* At this point:
+ /*
+ * At this point:
* act->pin updated to reflect mapping.
* sha->flags updated to indicate to granting domain mapping done.
* frame contains the mfn.
if ( (host_virt_addr != 0) && (dev_hst_ro_flags & GNTMAP_host_map) )
{
- /* Write update into the pagetable
- */
-
+ /* Write update into the pagetable. */
rc = update_grant_va_mapping( host_virt_addr,
(frame << PAGE_SHIFT) | _PAGE_PRESENT |
_PAGE_ACCESSED |
((dev_hst_ro_flags & GNTMAP_readonly) ? 0 : _PAGE_RW),
mapping_d, mapping_ed );
- /* IMPORTANT: (rc == 0) => must flush / invalidate entry in TLB.
+ /*
+ * IMPORTANT: (rc == 0) => must flush / invalidate entry in TLB.
* This is done in the outer gnttab_map_grant_ref.
*/
- if ( 0 > rc )
+ if ( rc < 0 )
{
- /* Abort. */
+ /* Failure: undo and abort. */
spin_lock(&granting_d->grant_table->lock);
if ( dev_hst_ro_flags & GNTMAP_readonly )
+ {
act->pin -= GNTPIN_hstr_inc;
+ }
else
{
act->pin -= GNTPIN_hstw_inc;
put_page_type(&frame_table[frame]);
}
}
+
if ( act->pin == 0 )
{
clear_bit(_GTF_reading, &sha->flags);
}
}
+
*pframe = frame;
return rc;
return rc;
}
+/*
+ * Returns 0 if TLB flush / invalidate required by caller.
+ * va will indicate the address to be invalidated.
+ */
static int
__gnttab_map_grant_ref(
gnttab_map_grant_ref_t *uop,
unsigned long frame = 0, host_virt_addr;
int rc;
- /* Returns 0 if TLB flush / invalidate required by caller.
- * va will indicate the address to be invalidated. */
-
led = current;
ld = led->domain;
}
- if ( ((host_virt_addr != 0) || (dev_hst_ro_flags & GNTMAP_host_map) ) &&
+ if ( ((host_virt_addr != 0) || (dev_hst_ro_flags & GNTMAP_host_map)) &&
unlikely(!__addr_ok(host_virt_addr)))
{
DPRINTK("Bad virtual address (%x) or flags (%x).\n",
}
if ( unlikely(ref >= NR_GRANT_ENTRIES) ||
- unlikely((dev_hst_ro_flags & (GNTMAP_device_map|GNTMAP_host_map)) ==
-0) )
+ unlikely((dev_hst_ro_flags &
+ (GNTMAP_device_map|GNTMAP_host_map)) == 0) )
{
DPRINTK("Bad ref (%d) or flags (%x).\n", ref, dev_hst_ro_flags);
(void)__put_user(GNTST_bad_gntref, &uop->handle);
return GNTST_bad_domain;
}
- /* get a maptrack handle */
+ /* Get a maptrack handle. */
if ( unlikely((handle = get_maptrack_handle(ld->grant_table)) == -1) )
{
int i;
grant_mapping_t *new_mt;
grant_table_t *lgt = ld->grant_table;
- /* grow the maptrack table */
- if ( (new_mt = (void *)alloc_xenheap_pages(lgt->maptrack_order + 1)) == NULL )
+ /* Grow the maptrack table. */
+ new_mt = (void *)alloc_xenheap_pages(lgt->maptrack_order + 1);
+ if ( new_mt == NULL )
{
put_domain(rd);
DPRINTK("No more map handles available\n");
dev_hst_ro_flags,
host_virt_addr, &frame)))
{
- /* Only make the maptrack live _after_ writing the pte,
- * in case we overwrite the same frame number, causing a
- * maptrack walk to find it
+ /*
+ * Only make the maptrack live _after_ writing the pte, in case we
+ * overwrite the same frame number, causing a maptrack walk to find it
*/
ld->grant_table->maptrack[handle].domid = dom;
gnttab_map_grant_ref_t *uop, unsigned int count)
{
int i, flush = 0;
- unsigned long va[8];
+ unsigned long va;
for ( i = 0; i < count; i++ )
- if ( __gnttab_map_grant_ref(&uop[i],
- &va[ (flush < 8 ? flush : 0) ] ) == 0)
+ if ( __gnttab_map_grant_ref(&uop[i], &va) == 0 )
flush++;
- if ( flush != 0 )
- {
- if ( flush <= 8 )
- for ( i = 0; i < flush; i++ )
- flush_tlb_one_mask(current->domain->cpuset, va[i]);
- else
- local_flush_tlb();
- }
+ if ( flush == 1 )
+ flush_tlb_one_mask(current->domain->cpuset, va);
+ else if ( flush != 0 )
+ flush_tlb_mask(current->domain->cpuset);
return 0;
}
(void)__put_user(GNTST_bad_domain, &uop->status);
return GNTST_bad_domain;
}
+
#if GRANT_DEBUG_VERBOSE
DPRINTK("Unmapping grant ref (%hu) for domain (%hu) with handle (%hu)\n",
ref, dom, handle);
spin_lock(&rd->grant_table->lock);
if ( frame == 0 )
+ {
frame = act->frame;
+ }
else if ( frame == GNTUNMAP_DEV_FROM_VIRT )
{
if ( !( flags & GNTMAP_device_map ) )
PIN_FAIL(unmap_out, GNTST_bad_dev_addr,
- "Bad frame number: frame not mapped for device access.\n");
+ "Bad frame number: frame not mapped for dev access.\n");
frame = act->frame;
- /* frame will be unmapped for device access below if virt addr ok */
+ /* Frame will be unmapped for device access below if virt addr okay. */
}
else
{
map->ref_and_flags &= ~GNTMAP_device_map;
(void)__put_user(0, &uop->dev_bus_addr);
- /* frame is now unmapped for device access */
+ /* Frame is now unmapped for device access. */
}
if ( (virt != 0) &&
unsigned long _ol1e;
pl1e = &linear_pg_table[l1_linear_offset(virt)];
-
+
if ( unlikely(__get_user(_ol1e, (unsigned long *)pl1e) != 0) )
{
DPRINTK("Could not find PTE entry for address %x\n", virt);
goto unmap_out;
}
- /* check that the virtual address supplied is actually
- * mapped to act->frame.
+ /*
+ * Check that the virtual address supplied is actually mapped to
+ * act->frame.
*/
if ( unlikely((_ol1e >> PAGE_SHIFT) != frame ))
{
goto unmap_out;
}
- /* Delete pagetable entry
- */
+ /* Delete pagetable entry. */
if ( unlikely(__put_user(0, (unsigned long *)pl1e)))
{
DPRINTK("Cannot delete PTE entry at %x for virtual address %x\n",
gnttab_unmap_grant_ref_t *uop, unsigned int count)
{
int i, flush = 0;
- unsigned long va[8];
+ unsigned long va;
for ( i = 0; i < count; i++ )
- if ( __gnttab_unmap_grant_ref(&uop[i],
- &va[ (flush < 8 ? flush : 0) ] ) == 0)
+ if ( __gnttab_unmap_grant_ref(&uop[i], &va) == 0 )
flush++;
- if ( flush != 0 )
- {
- if ( flush <= 8 )
- for ( i = 0; i < flush; i++ )
- flush_tlb_one_mask(current->domain->cpuset, va[i]);
- else
- local_flush_tlb();
- }
+ if ( flush == 1 )
+ flush_tlb_one_mask(current->domain->cpuset, va);
+ else if ( flush != 0 )
+ flush_tlb_mask(current->domain->cpuset);
return 0;
}
if ( unlikely(op.nr_frames > NR_GRANT_FRAMES) )
{
- DPRINTK("Xen only supports at most %d grant-table frames per domain.\n",
+ DPRINTK("Xen only supports up to %d grant-table frames per domain.\n",
NR_GRANT_FRAMES);
(void)put_user(GNTST_general_error, &uop->status);
return 0;
{
ASSERT(d->grant_table != NULL);
(void)put_user(GNTST_okay, &uop->status);
-
for ( i = 0; i < op.nr_frames; i++ )
- (void)put_user( (
- virt_to_phys( (char*)(d->grant_table->shared)+(i*PAGE_SIZE) )
- >> PAGE_SHIFT ), &uop->frame_list[i]);
+ (void)put_user(
+ (virt_to_phys(d->grant_table->shared) >> PAGE_SHIFT) + i,
+ &uop->frame_list[i]);
}
put_domain(d);
if ( sha_copy.flags )
{
- DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n",
+ DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) "
+ "dom:(%hu) frame:(%lx)\n",
op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame);
}
}
if ( act->pin )
{
- DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) dom:(%hu) frame:(%lx)\n",
+ DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) "
+ "dom:(%hu) frame:(%lx)\n",
op.dom, i, act->pin, act->domid, act->frame);
}
}
if ( maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK )
{
- DPRINTK("Grant: dom (%hu) MAP (%d) ref:(%hu) flags:(%x) dom:(%hu)\n",
+ DPRINTK("Grant: dom (%hu) MAP (%d) ref:(%hu) flags:(%x) "
+ "dom:(%hu)\n",
op.dom, i,
maptrack->ref_and_flags >> MAPTRACK_REF_SHIFT,
maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK,
* also traverse this.
*/
- /* Note: if the same frame is mapped multiple times, and then one of
+ /* Note: If the same frame is mapped multiple times, and then one of
* the ptes is overwritten, which maptrack handle gets invalidated?
- * Advice: don't do it.
+ * Advice: Don't do it. Explicitly unmap.
*/
unsigned int handle, ref, refcount;
{
map = &lgt->maptrack[handle];
-
- /* cwc22: if multiple grants of the same frame are disallowed,
- * then the readonly check here can be changed to cause an early abort
- * if we've matched on frame, but not on write permission.
- */
if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) &&
( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly))))
{
t->maptrack[i].ref_and_flags = (i+1) << MAPTRACK_REF_SHIFT;
/* Shared grant table. */
- if ( (t->shared = (void *)alloc_xenheap_pages(ORDER_GRANT_FRAMES)) == NULL )
+ t->shared = (void *)alloc_xenheap_pages(ORDER_GRANT_FRAMES);
+ if ( t->shared == NULL )
goto no_mem;
memset(t->shared, 0, NR_GRANT_FRAMES * PAGE_SIZE);
for ( i = 0; i < NR_GRANT_FRAMES; i++ )
{
- SHARE_PFN_WITH_DOMAIN(virt_to_page((char *)(t->shared)+(i*PAGE_SIZE)), d);
- machine_to_phys_mapping[ (virt_to_phys((char*)(t->shared)+(i*PAGE_SIZE))
- >> PAGE_SHIFT) ] = INVALID_M2P_ENTRY;
+ SHARE_PFN_WITH_DOMAIN(
+ virt_to_page((char *)(t->shared)+(i*PAGE_SIZE)), d);
+ machine_to_phys_mapping[(virt_to_phys(t->shared) >> PAGE_SHIFT) + i] =
+ INVALID_M2P_ENTRY;
}
/* Okay, install the structure. */
if ( rd != NULL )
put_domain(rd);
- printk(KERN_WARNING "Grant release: Could not find domain %d\n", dom);
+ printk(KERN_WARNING "Grant release: No dom%d\n", dom);
continue;
}
/* Free memory relating to this grant table. */
d->grant_table = NULL;
free_xenheap_pages((unsigned long)t->shared, ORDER_GRANT_FRAMES);
- free_xenheap_page((unsigned long)t->maptrack); //cwc22
+ free_xenheap_page((unsigned long)t->maptrack);
xfree(t->active);
xfree(t);
}